Skip to content

_quicksort overflow fix#6384

Closed
yowaimo2 wants to merge 2 commits intoOpenZeppelin:masterfrom
yowaimo2:master
Closed

_quicksort overflow fix#6384
yowaimo2 wants to merge 2 commits intoOpenZeppelin:masterfrom
yowaimo2:master

Conversation

@yowaimo2
Copy link

@yowaimo2 yowaimo2 commented Mar 2, 2026

Fixes #6289

Fixed the _quickSort implementation in Arrays.sol to prevent stack overflow errors on large or reverse-sorted arrays.

Changes- uses "while " in order to prevent the overflow because in (true) loop it just assign slots in one time and just swap there while in recursion slots give in each recursive state :)

@yowaimo2 yowaimo2 requested a review from a team as a code owner March 2, 2026 09:11
@changeset-bot
Copy link

changeset-bot bot commented Mar 2, 2026

⚠️ No Changeset found

Latest commit: f2e383b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 2, 2026

Walkthrough

The _quickSort function in contracts/utils/Arrays.sol has been refactored to use a loop-based approach combined with single recursion instead of the previous dual-recursion pattern. The optimization computes the pivot position, swaps it into place, then conditionally recurses only on the smaller partition while iteratively processing the larger partition by updating loop bounds. The base case condition remains unchanged. Function formatting has been adjusted to multiline style, and clarifying comments have been added to explain the control flow strategy. No modifications to public entity signatures were made.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title '_quicksort overflow fix' directly addresses the main change: preventing stack overflow in the _quickSort function by converting it to an iterative approach.
Description check ✅ Passed The description references issue #6289 and explains the core change: using a while loop instead of recursion to prevent stack overflow on large or reverse-sorted arrays.
Linked Issues check ✅ Passed The PR implements the primary objective from issue #6289: converting recursive calls to use an iterative loop approach that only recurses on the smaller partition, directly addressing the stack overflow problem identified in the issue.
Out of Scope Changes check ✅ Passed The changes are narrowly scoped to the _quickSort function optimization requested in issue #6289; no unrelated modifications to other areas were introduced.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
contracts/utils/Arrays.sol (1)

139-146: Skip recursive calls for partitions smaller than 2 elements

This branch still calls _quickSort on empty/singleton sides, which is safe but adds avoidable overhead in worst-case pivot distributions. Consider guarding recursion with a >= 0x40 size check.

♻️ Proposed micro-optimization
-            if (pos - begin < end - (pos + 0x20)) {
-                // left smaller → recurse left, loop on right
-                _quickSort(begin, pos, comp);
-                begin = pos + 0x20;
-            } else {
-                // right smaller or equal → recurse right, loop on left
-                _quickSort(pos + 0x20, end, comp);
-                end = pos;
-            }
+            uint256 rightBegin = pos + 0x20;
+            uint256 leftSize = pos - begin;
+            uint256 rightSize = end - rightBegin;
+
+            if (leftSize < rightSize) {
+                // left smaller → recurse left, loop on right
+                if (leftSize >= 0x40) _quickSort(begin, pos, comp);
+                begin = rightBegin;
+            } else {
+                // right smaller or equal → recurse right, loop on left
+                if (rightSize >= 0x40) _quickSort(rightBegin, end, comp);
+                end = pos;
+            }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@contracts/utils/Arrays.sol` around lines 139 - 146, The _quickSort branch
currently recurses on partitions that may be empty or singleton; add explicit
size guards so you only recurse when a partition has at least two elements (>=
0x40 bytes). Specifically, before calling _quickSort(begin, pos, comp) ensure
(pos - begin) >= 0x40, and before calling _quickSort(pos + 0x20, end, comp)
ensure (end - (pos + 0x20)) >= 0x40; keep the existing loop-by-tail logic
(updating begin = pos + 0x20 or end = pos) when the guarded recursion is skipped
so behavior is unchanged. Include checks around the recursive calls in the
_quickSort function using the existing variables begin, end, pos, 0x20 and 0x40.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@contracts/utils/Arrays.sol`:
- Around line 139-146: The _quickSort branch currently recurses on partitions
that may be empty or singleton; add explicit size guards so you only recurse
when a partition has at least two elements (>= 0x40 bytes). Specifically, before
calling _quickSort(begin, pos, comp) ensure (pos - begin) >= 0x40, and before
calling _quickSort(pos + 0x20, end, comp) ensure (end - (pos + 0x20)) >= 0x40;
keep the existing loop-by-tail logic (updating begin = pos + 0x20 or end = pos)
when the guarded recursion is skipped so behavior is unchanged. Include checks
around the recursive calls in the _quickSort function using the existing
variables begin, end, pos, 0x20 and 0x40.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ca6f5fa and b122e7f.

📒 Files selected for processing (1)
  • contracts/utils/Arrays.sol

@Amxx
Copy link
Collaborator

Amxx commented Mar 2, 2026

Duplicate of #6324

@Amxx Amxx marked this as a duplicate of #6324 Mar 2, 2026
@Amxx Amxx closed this Mar 2, 2026
@Moses-main

This comment was marked as spam.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Function _quickSort() can be optimized

3 participants